package com.dinghui.mybatis.utils;

import org.apache.commons.lang3.StringUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Properties;

/**
 * by zlm 2018/11/28
 */
public class FastDFSClient {

    private TrackerClient trackerClient = null;
    private TrackerServer trackerServer = null;
    private StorageServer storageServer = null;
    private StorageClient1 storageClient = null;
    String groupName=null;//组名
    String storageFileName=null;//储存文件名
    String suffix=null;//文件后缀名
    public FastDFSClient(String conf) throws Exception {
    	Properties pro = new Properties(); // 使用ClassLoader加载properties配置文件生成对应的输入流
    	InputStream in = FastDFSClient.class.getClassLoader().getResourceAsStream("client.properties"); // 使用properties对象加载输入流 properties.load(in); ClientGlobal.initByProperties(properties);
		pro.load(in);
		ClientGlobal.initByProperties( pro);  //原方法
        /*
    	if (conf.contains("classpath:")) {
            conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
            System.out.println(conf);
        }
        ClientGlobal.init(conf)*/
        trackerClient = new TrackerClient();
        trackerServer = trackerClient.getConnection();
        storageServer = null;
        storageClient = new StorageClient1(trackerServer, storageServer);
    }
    /**
     * 需求：上传文件,不带后缀名，后缀名用文件自带后缀
     * 参数：
     * 上传文件地址,String fileName,如"F:\\zhoulemei\\images\\timg.jpg";"
     * 返回值：返回文件储存文件地址：组名+文件名   如："group1/M00/00/00/wKgAaVv-eyaAGhVzAAHRV-5OSGo692.jpg"
     */
    public  String uploadFile(String fileName) throws Exception{
        try {

            System.out.println("java.version=" + System.getProperty("java.version"));
            System.out.println("network_timeout=" + ClientGlobal.g_network_timeout + "ms");
            System.out.println("charset=" + ClientGlobal.g_charset);

            NameValuePair[] metaList = new NameValuePair[1];
            metaList[0] = new NameValuePair("fileName", fileName);
            String fileId = storageClient.upload_file1(fileName, null, metaList);
            System.out.println("upload success. file id is: " + fileId);

            byte[] result = storageClient.download_file1(fileId);
            System.out.println("download result is: " + result.length);
            trackerServer.close();

            return fileId;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 需求：上传文件,带后缀名，自定义文件后缀名
     * 参数：
     * 上传文件地址,String fileName,如"F:\\zhoulemei\\images\\timg.jpg";"
     * 文件后缀名,String suffix,如"png"
     * 返回值：返回文件储存文件地址：组名+文件名   如："group1/M00/00/00/wKgAaVv-eyaAGhVzAAHRV-5OSGo692.jpg"
     */
    public  String uploadFileWithSuffix(String fileName,String suffix) throws Exception{
        try {

            System.out.println("java.version=" + System.getProperty("java.version"));
            System.out.println("network_timeout=" + ClientGlobal.g_network_timeout + "ms");
            System.out.println("charset=" + ClientGlobal.g_charset);

            NameValuePair[] metaList = new NameValuePair[1];
            metaList[0] = new NameValuePair("fileName", fileName);
            String fileId = storageClient.upload_file1(fileName, suffix, null);
            System.out.println("upload success. file id is: " + fileId);

            byte[] result = storageClient.download_file1(fileId);
            System.out.println("download result is: " + result.length);
            trackerServer.close();

            return fileId;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }


    /**
     * 需求：下载文件，成功返回true，失败返回false
     * 参数：
     * 文件访问地址：String fileUrl,如"http://192.168.0.108/fastdfs/group1/M00/00/00/wKgAaFv_P5qADVhwAAWSoyqEAvw69.docx"
     * 文件名：String fileName,如"我的图片",是文件保存在数据库的名称
     * 保存文件的地址：String targetPath,如"d:\\temp\\"
     */
    //文件访问地址：
    @SuppressWarnings("unused")
    public Boolean downloadFile(String fileUrl,String fileName,String targetPath) throws Exception{
        try {
            //如果文件名为空，则随机生成文件名
            if(StringUtils.isBlank(fileName)) {
                fileName=RandomStringUtil.getStringRandom(6);
            }

            //截取组名，存储文件名，和文件后缀名
            if(StringUtils.isNotBlank(fileUrl)) {
                //组名
                Integer index1 = fileUrl.indexOf("gro");
                Integer index2 = fileUrl.indexOf("/M");
                groupName=fileUrl.substring(index1,index2);
                //System.out.println("组名："+groupName);
                //存储文件名
                Integer index3 = fileUrl.indexOf("M");
                storageFileName=fileUrl.substring(index3);
                //System.out.println("储存文件名："+storageFileName);
                //文件后缀名filename.lastIndexOf(".")+1
                Integer index4 = fileUrl.lastIndexOf(".");
                suffix=fileUrl.substring(index4);
                //System.out.println("文件后缀名："+suffix);
            }
            //System.out.println("文件名："+fileName);
            byte[] b = storageClient.download_file(groupName,storageFileName);
            if (b != null) {
                System.out.println(b.length);
                //return saveFile(b, "d:\\temp\\",RandomStringUtil.getStringRandom(5) + ".jpg");
                return saveFile(b, targetPath, fileName+suffix);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    public boolean downloadFile(String fileUrl, String fileName, HttpServletResponse response) throws Exception{
        try {
            //如果文件名为空，则随机生成文件名
            if(StringUtils.isBlank(fileName)) {
                fileName=RandomStringUtil.getStringRandom(6);
            }

            //截取组名，存储文件名，和文件后缀名
            if(StringUtils.isNotBlank(fileUrl)) {
                //组名
                Integer index1 = fileUrl.indexOf("gro");
                Integer index2 = fileUrl.indexOf("/M");
                groupName=fileUrl.substring(index1,index2);
                //System.out.println("组名："+groupName);
                //存储文件名
                Integer index3 = fileUrl.indexOf("M");
                storageFileName=fileUrl.substring(index3);
                //System.out.println("储存文件名："+storageFileName);
                //文件后缀名filename.lastIndexOf(".")+1
                Integer index4 = fileUrl.lastIndexOf(".");
                suffix=fileUrl.substring(index4);
                //System.out.println("文件后缀名："+suffix);
            }
            String name=fileName+suffix;
            //System.out.println("文件名："+fileName);
            byte[] b = storageClient.download_file(groupName,storageFileName);
            if (b != null) {
                response.reset();
                response.setContentType("bin");
                //response.setHeader("Content-Type","application/vnd.ms-excel;charset=UTF-8");
                response.setHeader("Content-Disposition", "attachment;fileName=" + new String(name.getBytes("UTF-8"),"iso-8859-1")+";fileName*=utf-8''"+new String(name.getBytes("UTF-8"),"iso-8859-1"));
//				String $file_name=rawurlencode(name);
//				response.setHeader("Content-Disposition", "attachment;fileName='$encoded_fname';fileName*=utf-8''$encoded_fname");
                response.getOutputStream().write(b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 需求：下载文件调用方法，将字节流写到磁盘生成文件
     */
    @SuppressWarnings({ "finally", "resource" })
    private Boolean saveFile(byte[] b, String targetPath, String fileName) throws Exception{
        @SuppressWarnings("unused")
        Boolean ret;
        File file = new File(targetPath + fileName);
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);

            fileOutputStream.write(b);

            return ret=true;

        } catch (FileNotFoundException e) {
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

        }
        return ret=false;
    }
    /**
     * 需求：获取文件信息
     * 参数：
     * 文件访问地址：String fileUrl,如"http://192.168.0.108/fastdfs/group1/M00/00/00/wKgAaFv_P5qADVhwAAWSoyqEAvw69.docx"
     * 返回值：
     * 返回文件信息对象 FileInfo fi
     * 获取信息：
     * 储存服务器地址：fi.getSourceIpAddr()
     * 文件大小：fi.getFileSize() byte
     * 存储时间：DateUtil.toString(fi.getCreateTimestamp()),如"2018-11-29 09:23:38"
     * crc32校验码：fi.getCrc32()
     */
    public FileInfo getFileInfo(String fileUrl) throws Exception{
        try {
            //截取组名，存储文件名，和文件后缀名
            if(StringUtils.isNotBlank(fileUrl)) {
                //组名
                Integer index1 = fileUrl.indexOf("gro");
                Integer index2 = fileUrl.indexOf("/M");
                groupName=fileUrl.substring(index1,index2);
                //System.out.println("组名："+groupName);
                //存储文件名
                Integer index3 = fileUrl.indexOf("M");
                storageFileName=fileUrl.substring(index3);
                //System.out.println("储存文件名："+storageFileName);
            }
            FileInfo fi = storageClient.get_file_info(groupName, storageFileName);
			/*System.out.println("储存服务器地址："+fi.getSourceIpAddr());
			System.out.println("文件大小："+fi.getFileSize()+" byte");
			System.out.println("存储时间："+DateUtil.toString(fi.getCreateTimestamp()));
			System.out.println("crc32校验码："+fi.getCrc32());*/
            return fi;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 需求：获取文件自定义的mate信息(key、value)
     * 参数：
     * 文件访问地址：String fileUrl,如"http://192.168.0.108/fastdfs/group1/M00/00/00/wKgAaFv_P5qADVhwAAWSoyqEAvw69.docx"
     * 返回值：NameValuePair nvps[]
     * 获取信息:
     * 遍历nvps[]数据，根据key获取value
     *
     */
    public NameValuePair GetFileMateInfo(String fileUrl) throws Exception{
        try {
            //截取组名，存储文件名，和文件后缀名
            if(StringUtils.isNotBlank(fileUrl)) {
                //组名
                Integer index1 = fileUrl.indexOf("gro");
                Integer index2 = fileUrl.indexOf("/M");
                groupName=fileUrl.substring(index1,index2);
                //System.out.println("组名："+groupName);
                //存储文件名
                Integer index3 = fileUrl.indexOf("M");
                storageFileName=fileUrl.substring(index3);
                //System.out.println("储存文件名："+storageFileName);
            }
            NameValuePair nvps[] = storageClient.get_metadata(groupName,storageFileName);

            if (nvps != null) {
                for (NameValuePair nvp : nvps) {
                    //System.out.println(nvp.getName() + ":" + nvp.getValue());
                    return nvp;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 需求：删除文件,从操作系统storage节点,物理删除/home/FastDFS/fdfs_storage/data/00/00直接消失
     * 参数：
     * 文件访问地址：String fileUrl,如"http://192.168.0.108/fastdfs/group1/M00/00/00/wKgAaFv_P5qADVhwAAWSoyqEAvw69.docx"
     * 返回值：
     * 成功返回true，失败返回false
     */
    public Boolean deleteFile(String fileUrl) throws Exception{
        try {
            //截取组名，存储文件名，和文件后缀名
            if(StringUtils.isNotBlank(fileUrl)) {
                //组名
                Integer index1 = fileUrl.indexOf("gro");
                Integer index2 = fileUrl.indexOf("/M");
                groupName=fileUrl.substring(index1,index2);
                //System.out.println("组名："+groupName);
                //存储文件名
                Integer index3 = fileUrl.indexOf("M");
                storageFileName=fileUrl.substring(index3);
                //System.out.println("储存文件名："+storageFileName);
            }
            int i = storageClient.delete_file(groupName, storageFileName);
            //System.out.println(i == 0 ? "删除成功" : "删除失败:" + i);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 上传文件方法,springmvc调用此方法
     * <p>Title: uploadFile</p>
     * @param fileContent 文件的内容，字节数组
     * @param extName 文件扩展名
     * @param metas 文件扩展信息
     * @return "group1/M00/00/00/wKgAaVv-eyaAGhVzAAHRV-5OSGo692.jpg"
     * @throws Exception
     */
    public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {

        String result = storageClient.upload_file1(fileContent, extName, metas);
        return result;
    }

    public String uploadFile(byte[] fileContent) throws Exception {
        return uploadFile(fileContent, null, null);
    }

    public String uploadFile(byte[] fileContent, String extName) throws Exception {
        return uploadFile(fileContent, extName, null);
    }

    /**
     * 上传文件方法
     * <p>Title: uploadFile</p>
     * <p>Description: </p>
     * @param fileName 文件全路径
     * @param extName 文件扩展名，不包含（.）
     * @param metas 文件扩展信息
     * @return "group1/M00/00/00/wKgAaVv-eyaAGhVzAAHRV-5OSGo692.jpg"
     * @throws Exception
     */
    public String uploadFile2(String fileName, String extName, NameValuePair[] metas) throws Exception {
        String result = storageClient.upload_file1(fileName, extName, metas);
        return result;
    }

    public String uploadFile2(String fileName) throws Exception {
        return uploadFile2(fileName, null, null);
    }

    public String uploadFile2(String fileName, String extName) throws Exception {
        return uploadFile2(fileName, extName, null);
    }

}
